/**
 *
 */
package com.im.service.jim.processor;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjUtil;
import com.im.service.domain.entity.ImGroup;
import com.im.service.domain.entity.ImUser;
import com.im.service.service.ImFriendService;
import com.im.service.service.ImGroupUserService;
import com.im.service.service.ImUserService;
import lombok.extern.slf4j.Slf4j;
import org.jim.core.ImChannelContext;
import org.jim.core.packets.*;
import org.jim.server.processor.login.LoginCmdProcessor;
import org.jim.server.protocol.AbstractProtocolCmdProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author WChao
 */
@Slf4j
@Component
public class LoginServiceProcessor extends AbstractProtocolCmdProcessor implements LoginCmdProcessor {

    @Autowired
    private ImGroupUserService groupUserService;
    @Autowired
    private ImUserService userService;
    @Autowired
    private ImFriendService friendService;

    /**
     * 根据用户名和密码获取用户
     *
     * @param loginReqBody
     * @param imChannelContext
     * @return
     */
    public User getUser(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
        Object loginId = StpUtil.getLoginIdByToken(loginReqBody.getToken());
        ImUser imUser = userService.getById(String.valueOf(loginId));
        if (ObjUtil.isNull(imUser)) {
            return User.newBuilder().build();
        }
        User user = getUser(imUser);
        return user;
    }

    /**
     * 根据token获取用户信息
     *
     * @param imUser
     * @return
     * @author: WChao
     */
    public User getUser(ImUser imUser) {
        User.Builder builder = User.newBuilder();
        // 我得群组
        List<ImGroup> groupList = groupUserService.getGroupListByUserId(imUser.getId());
        if (CollectionUtil.isNotEmpty(groupList)) {
            for (ImGroup imGroup : groupList) {
                builder.addGroup(Group.newBuilder()
                        .avatar(imGroup.getAvatar())
                        .groupId(String.valueOf(imGroup.getId())).name(imGroup.getGroupName()).build());
            }
        }
        // 我的好友
        List<ImUser> friendList = friendService.getFriendsByUserId(imUser.getId());
        if (CollectionUtil.isNotEmpty(friendList)) {
            Group myFriend = Group.newBuilder().groupId("1").name("我的好友").build();
            List<User> myFriendGroupUsers = new ArrayList();
            for (ImUser friend : friendList) {
                User friendUser = User.newBuilder()
                        .userId(String.valueOf(friend.getId()))
                        .avatar(friend.getAvatar())
                        .nick(friend.getNickname())
                        .build();
                myFriendGroupUsers.add(friendUser);
            }
            myFriend.setUsers(myFriendGroupUsers);
            builder.addFriend(myFriend);
        }
        builder
                .userId(String.valueOf(imUser.getId()))
                .nick(imUser.getNickname())
                .avatar(imUser.getAvatar())
                .status(UserStatusType.ONLINE.getStatus());
        User user = builder.build();
        return user;
    }

    /**
     * 登陆成功返回状态码:ImStatus.C10007
     * 登录失败返回状态码:ImStatus.C10008
     * 注意：只要返回非成功状态码(ImStatus.C10007),其他状态码均为失败,此时用户可以自定义返回状态码，定义返回前端失败信息
     */
    @Override
    public LoginRespBody doLogin(LoginReqBody loginReqBody, ImChannelContext imChannelContext) {
        if (Objects.nonNull(loginReqBody.getToken())) {
            Object userId = StpUtil.getLoginIdByToken(loginReqBody.getToken());
            if (ObjUtil.isNotNull(userId)) {
                return LoginRespBody.success();
            } else {
                return LoginRespBody.failed();
            }
        } else {
            return LoginRespBody.failed();
        }
    }

    @Override
    public void onSuccess(User user, ImChannelContext channelContext) {
        log.info("登录成功回调方法");
    }

    @Override
    public void onFailed(ImChannelContext imChannelContext) {
        log.info("登录失败回调方法");
    }
}
